#ifndef     __HEAT_TASK_H
#define     __HEAT_TASK_H

#include "../../rtos/thread.h"
#include "../../rtos/sync_value.h"
#include "../../utils/object.h"

namespace task {

class HeatTask : public rtos::Thread<HeatTask, 1024, osPriorityHigh1> {

public:
    enum class State : uint8_t {
        IDLE = 0,
        PRE_WORK = 1,
        FAIL = 2,
    };

    struct HeatInfo {
        uint8_t water;
        uint8_t steam;
    };

    void heat(uint8_t water, uint8_t steam) {
        m_heat_info.water = water;
        m_heat_info.steam = steam;
        m_sync.set(State::PRE_WORK);
    }

    bool steam_valid(uint8_t steam) {
        return (steam <= m_heat_info.steam) && (m_state == State::PRE_WORK);
    }

    bool water_valid(uint8_t water) {
        return (water <= m_heat_info.water) && (m_state == State::PRE_WORK);
    }

    inline void stop() { m_sync.set(State::IDLE);}

    inline uint8_t state() { return static_cast<uint8_t>(m_state); }

    void run();

private:
    bool wait(uint32_t timeout = osWaitForever) { return m_sync.get(m_state, timeout); }
    
    void do_idle();
    void do_pre_work();
    void do_stop();

    rtos::SyncValue<State> m_sync;
    State m_state = State::IDLE;
    HeatInfo m_heat_info;
};

inline utils::Object<HeatTask> heatTask;

}


#endif
